// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// ███╗   ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
// ████╗  ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
// ██╔██╗ ██║██║   ██║   ██║   ██║██║     █████╗
// ██║╚██╗██║██║   ██║   ██║   ██║██║     ██╔══╝
// ██║ ╚████║╚██████╔╝   ██║   ██║╚██████╗███████╗
// ╚═╝  ╚═══╝ ╚═════╝    ╚═╝   ╚═╝ ╚═════╝╚══════╝
// ------------------------------------------------
//
// This file is automatically generated.
// Please do not edit these files manually.
//
// ------------------------------------------------

#nullable restore

using Elastic.Clients.Elasticsearch.Serverless.Fluent;
using Elastic.Clients.Elasticsearch.Serverless.Serialization;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Elastic.Clients.Elasticsearch.Serverless.Core.Search;

public sealed partial class TermSuggester
{
	[JsonInclude, JsonPropertyName("analyzer")]
	public string? Analyzer { get; set; }
	[JsonInclude, JsonPropertyName("field")]
	public Elastic.Clients.Elasticsearch.Serverless.Field Field { get; set; }
	[JsonInclude, JsonPropertyName("lowercase_terms")]
	public bool? LowercaseTerms { get; set; }

	/// <summary>
	/// <para>The maximum edit distance candidate suggestions can have in order to be considered as a suggestion.<br/>Can only be `1` or `2`.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("max_edits")]
	public int? MaxEdits { get; set; }

	/// <summary>
	/// <para>A factor that is used to multiply with the shard_size in order to inspect more candidate spelling corrections on the shard level.<br/>Can improve accuracy at the cost of performance.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("max_inspections")]
	public int? MaxInspections { get; set; }

	/// <summary>
	/// <para>The maximum threshold in number of documents in which a suggest text token can exist in order to be included.<br/>Can be a relative percentage number (for example `0.4`) or an absolute number to represent document frequencies.<br/>If a value higher than 1 is specified, then fractional can not be specified.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("max_term_freq")]
	public float? MaxTermFreq { get; set; }

	/// <summary>
	/// <para>The minimal threshold in number of documents a suggestion should appear in.<br/>This can improve quality by only suggesting high frequency terms.<br/>Can be specified as an absolute number or as a relative percentage of number of documents.<br/>If a value higher than 1 is specified, then the number cannot be fractional.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("min_doc_freq")]
	public float? MinDocFreq { get; set; }

	/// <summary>
	/// <para>The minimum length a suggest text term must have in order to be included.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("min_word_length")]
	public int? MinWordLength { get; set; }

	/// <summary>
	/// <para>The number of minimal prefix characters that must match in order be a candidate for suggestions.<br/>Increasing this number improves spellcheck performance.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("prefix_length")]
	public int? PrefixLength { get; set; }

	/// <summary>
	/// <para>Sets the maximum number of suggestions to be retrieved from each individual shard.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("shard_size")]
	public int? ShardSize { get; set; }
	[JsonInclude, JsonPropertyName("size")]
	public int? Size { get; set; }

	/// <summary>
	/// <para>Defines how suggestions should be sorted per suggest text term.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("sort")]
	public Elastic.Clients.Elasticsearch.Serverless.Core.Search.SuggestSort? Sort { get; set; }

	/// <summary>
	/// <para>The string distance implementation to use for comparing how similar suggested terms are.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("string_distance")]
	public Elastic.Clients.Elasticsearch.Serverless.Core.Search.StringDistance? StringDistance { get; set; }

	/// <summary>
	/// <para>Controls what suggestions are included or controls for what suggest text terms, suggestions should be suggested.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("suggest_mode")]
	public Elastic.Clients.Elasticsearch.Serverless.SuggestMode? SuggestMode { get; set; }

	/// <summary>
	/// <para>The suggest text.<br/>Needs to be set globally or per suggestion.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("text")]
	public string? Text { get; set; }

	public static implicit operator FieldSuggester(TermSuggester termSuggester) => Core.Search.FieldSuggester.Term(termSuggester);
}

public sealed partial class TermSuggesterDescriptor<TDocument> : SerializableDescriptor<TermSuggesterDescriptor<TDocument>>
{
	internal TermSuggesterDescriptor(Action<TermSuggesterDescriptor<TDocument>> configure) => configure.Invoke(this);

	public TermSuggesterDescriptor() : base()
	{
	}

	private string? AnalyzerValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Field FieldValue { get; set; }
	private bool? LowercaseTermsValue { get; set; }
	private int? MaxEditsValue { get; set; }
	private int? MaxInspectionsValue { get; set; }
	private float? MaxTermFreqValue { get; set; }
	private float? MinDocFreqValue { get; set; }
	private int? MinWordLengthValue { get; set; }
	private int? PrefixLengthValue { get; set; }
	private int? ShardSizeValue { get; set; }
	private int? SizeValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Core.Search.SuggestSort? SortValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Core.Search.StringDistance? StringDistanceValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.SuggestMode? SuggestModeValue { get; set; }
	private string? TextValue { get; set; }

	public TermSuggesterDescriptor<TDocument> Analyzer(string? analyzer)
	{
		AnalyzerValue = analyzer;
		return Self;
	}

	public TermSuggesterDescriptor<TDocument> Field(Elastic.Clients.Elasticsearch.Serverless.Field field)
	{
		FieldValue = field;
		return Self;
	}

	public TermSuggesterDescriptor<TDocument> Field<TValue>(Expression<Func<TDocument, TValue>> field)
	{
		FieldValue = field;
		return Self;
	}

	public TermSuggesterDescriptor<TDocument> LowercaseTerms(bool? lowercaseTerms = true)
	{
		LowercaseTermsValue = lowercaseTerms;
		return Self;
	}

	/// <summary>
	/// <para>The maximum edit distance candidate suggestions can have in order to be considered as a suggestion.<br/>Can only be `1` or `2`.</para>
	/// </summary>
	public TermSuggesterDescriptor<TDocument> MaxEdits(int? maxEdits)
	{
		MaxEditsValue = maxEdits;
		return Self;
	}

	/// <summary>
	/// <para>A factor that is used to multiply with the shard_size in order to inspect more candidate spelling corrections on the shard level.<br/>Can improve accuracy at the cost of performance.</para>
	/// </summary>
	public TermSuggesterDescriptor<TDocument> MaxInspections(int? maxInspections)
	{
		MaxInspectionsValue = maxInspections;
		return Self;
	}

	/// <summary>
	/// <para>The maximum threshold in number of documents in which a suggest text token can exist in order to be included.<br/>Can be a relative percentage number (for example `0.4`) or an absolute number to represent document frequencies.<br/>If a value higher than 1 is specified, then fractional can not be specified.</para>
	/// </summary>
	public TermSuggesterDescriptor<TDocument> MaxTermFreq(float? maxTermFreq)
	{
		MaxTermFreqValue = maxTermFreq;
		return Self;
	}

	/// <summary>
	/// <para>The minimal threshold in number of documents a suggestion should appear in.<br/>This can improve quality by only suggesting high frequency terms.<br/>Can be specified as an absolute number or as a relative percentage of number of documents.<br/>If a value higher than 1 is specified, then the number cannot be fractional.</para>
	/// </summary>
	public TermSuggesterDescriptor<TDocument> MinDocFreq(float? minDocFreq)
	{
		MinDocFreqValue = minDocFreq;
		return Self;
	}

	/// <summary>
	/// <para>The minimum length a suggest text term must have in order to be included.</para>
	/// </summary>
	public TermSuggesterDescriptor<TDocument> MinWordLength(int? minWordLength)
	{
		MinWordLengthValue = minWordLength;
		return Self;
	}

	/// <summary>
	/// <para>The number of minimal prefix characters that must match in order be a candidate for suggestions.<br/>Increasing this number improves spellcheck performance.</para>
	/// </summary>
	public TermSuggesterDescriptor<TDocument> PrefixLength(int? prefixLength)
	{
		PrefixLengthValue = prefixLength;
		return Self;
	}

	/// <summary>
	/// <para>Sets the maximum number of suggestions to be retrieved from each individual shard.</para>
	/// </summary>
	public TermSuggesterDescriptor<TDocument> ShardSize(int? shardSize)
	{
		ShardSizeValue = shardSize;
		return Self;
	}

	public TermSuggesterDescriptor<TDocument> Size(int? size)
	{
		SizeValue = size;
		return Self;
	}

	/// <summary>
	/// <para>Defines how suggestions should be sorted per suggest text term.</para>
	/// </summary>
	public TermSuggesterDescriptor<TDocument> Sort(Elastic.Clients.Elasticsearch.Serverless.Core.Search.SuggestSort? sort)
	{
		SortValue = sort;
		return Self;
	}

	/// <summary>
	/// <para>The string distance implementation to use for comparing how similar suggested terms are.</para>
	/// </summary>
	public TermSuggesterDescriptor<TDocument> StringDistance(Elastic.Clients.Elasticsearch.Serverless.Core.Search.StringDistance? stringDistance)
	{
		StringDistanceValue = stringDistance;
		return Self;
	}

	/// <summary>
	/// <para>Controls what suggestions are included or controls for what suggest text terms, suggestions should be suggested.</para>
	/// </summary>
	public TermSuggesterDescriptor<TDocument> SuggestMode(Elastic.Clients.Elasticsearch.Serverless.SuggestMode? suggestMode)
	{
		SuggestModeValue = suggestMode;
		return Self;
	}

	/// <summary>
	/// <para>The suggest text.<br/>Needs to be set globally or per suggestion.</para>
	/// </summary>
	public TermSuggesterDescriptor<TDocument> Text(string? text)
	{
		TextValue = text;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (!string.IsNullOrEmpty(AnalyzerValue))
		{
			writer.WritePropertyName("analyzer");
			writer.WriteStringValue(AnalyzerValue);
		}

		writer.WritePropertyName("field");
		JsonSerializer.Serialize(writer, FieldValue, options);
		if (LowercaseTermsValue.HasValue)
		{
			writer.WritePropertyName("lowercase_terms");
			writer.WriteBooleanValue(LowercaseTermsValue.Value);
		}

		if (MaxEditsValue.HasValue)
		{
			writer.WritePropertyName("max_edits");
			writer.WriteNumberValue(MaxEditsValue.Value);
		}

		if (MaxInspectionsValue.HasValue)
		{
			writer.WritePropertyName("max_inspections");
			writer.WriteNumberValue(MaxInspectionsValue.Value);
		}

		if (MaxTermFreqValue.HasValue)
		{
			writer.WritePropertyName("max_term_freq");
			writer.WriteNumberValue(MaxTermFreqValue.Value);
		}

		if (MinDocFreqValue.HasValue)
		{
			writer.WritePropertyName("min_doc_freq");
			writer.WriteNumberValue(MinDocFreqValue.Value);
		}

		if (MinWordLengthValue.HasValue)
		{
			writer.WritePropertyName("min_word_length");
			writer.WriteNumberValue(MinWordLengthValue.Value);
		}

		if (PrefixLengthValue.HasValue)
		{
			writer.WritePropertyName("prefix_length");
			writer.WriteNumberValue(PrefixLengthValue.Value);
		}

		if (ShardSizeValue.HasValue)
		{
			writer.WritePropertyName("shard_size");
			writer.WriteNumberValue(ShardSizeValue.Value);
		}

		if (SizeValue.HasValue)
		{
			writer.WritePropertyName("size");
			writer.WriteNumberValue(SizeValue.Value);
		}

		if (SortValue is not null)
		{
			writer.WritePropertyName("sort");
			JsonSerializer.Serialize(writer, SortValue, options);
		}

		if (StringDistanceValue is not null)
		{
			writer.WritePropertyName("string_distance");
			JsonSerializer.Serialize(writer, StringDistanceValue, options);
		}

		if (SuggestModeValue is not null)
		{
			writer.WritePropertyName("suggest_mode");
			JsonSerializer.Serialize(writer, SuggestModeValue, options);
		}

		if (!string.IsNullOrEmpty(TextValue))
		{
			writer.WritePropertyName("text");
			writer.WriteStringValue(TextValue);
		}

		writer.WriteEndObject();
	}
}

public sealed partial class TermSuggesterDescriptor : SerializableDescriptor<TermSuggesterDescriptor>
{
	internal TermSuggesterDescriptor(Action<TermSuggesterDescriptor> configure) => configure.Invoke(this);

	public TermSuggesterDescriptor() : base()
	{
	}

	private string? AnalyzerValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Field FieldValue { get; set; }
	private bool? LowercaseTermsValue { get; set; }
	private int? MaxEditsValue { get; set; }
	private int? MaxInspectionsValue { get; set; }
	private float? MaxTermFreqValue { get; set; }
	private float? MinDocFreqValue { get; set; }
	private int? MinWordLengthValue { get; set; }
	private int? PrefixLengthValue { get; set; }
	private int? ShardSizeValue { get; set; }
	private int? SizeValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Core.Search.SuggestSort? SortValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Core.Search.StringDistance? StringDistanceValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.SuggestMode? SuggestModeValue { get; set; }
	private string? TextValue { get; set; }

	public TermSuggesterDescriptor Analyzer(string? analyzer)
	{
		AnalyzerValue = analyzer;
		return Self;
	}

	public TermSuggesterDescriptor Field(Elastic.Clients.Elasticsearch.Serverless.Field field)
	{
		FieldValue = field;
		return Self;
	}

	public TermSuggesterDescriptor Field<TDocument, TValue>(Expression<Func<TDocument, TValue>> field)
	{
		FieldValue = field;
		return Self;
	}

	public TermSuggesterDescriptor Field<TDocument>(Expression<Func<TDocument, object>> field)
	{
		FieldValue = field;
		return Self;
	}

	public TermSuggesterDescriptor LowercaseTerms(bool? lowercaseTerms = true)
	{
		LowercaseTermsValue = lowercaseTerms;
		return Self;
	}

	/// <summary>
	/// <para>The maximum edit distance candidate suggestions can have in order to be considered as a suggestion.<br/>Can only be `1` or `2`.</para>
	/// </summary>
	public TermSuggesterDescriptor MaxEdits(int? maxEdits)
	{
		MaxEditsValue = maxEdits;
		return Self;
	}

	/// <summary>
	/// <para>A factor that is used to multiply with the shard_size in order to inspect more candidate spelling corrections on the shard level.<br/>Can improve accuracy at the cost of performance.</para>
	/// </summary>
	public TermSuggesterDescriptor MaxInspections(int? maxInspections)
	{
		MaxInspectionsValue = maxInspections;
		return Self;
	}

	/// <summary>
	/// <para>The maximum threshold in number of documents in which a suggest text token can exist in order to be included.<br/>Can be a relative percentage number (for example `0.4`) or an absolute number to represent document frequencies.<br/>If a value higher than 1 is specified, then fractional can not be specified.</para>
	/// </summary>
	public TermSuggesterDescriptor MaxTermFreq(float? maxTermFreq)
	{
		MaxTermFreqValue = maxTermFreq;
		return Self;
	}

	/// <summary>
	/// <para>The minimal threshold in number of documents a suggestion should appear in.<br/>This can improve quality by only suggesting high frequency terms.<br/>Can be specified as an absolute number or as a relative percentage of number of documents.<br/>If a value higher than 1 is specified, then the number cannot be fractional.</para>
	/// </summary>
	public TermSuggesterDescriptor MinDocFreq(float? minDocFreq)
	{
		MinDocFreqValue = minDocFreq;
		return Self;
	}

	/// <summary>
	/// <para>The minimum length a suggest text term must have in order to be included.</para>
	/// </summary>
	public TermSuggesterDescriptor MinWordLength(int? minWordLength)
	{
		MinWordLengthValue = minWordLength;
		return Self;
	}

	/// <summary>
	/// <para>The number of minimal prefix characters that must match in order be a candidate for suggestions.<br/>Increasing this number improves spellcheck performance.</para>
	/// </summary>
	public TermSuggesterDescriptor PrefixLength(int? prefixLength)
	{
		PrefixLengthValue = prefixLength;
		return Self;
	}

	/// <summary>
	/// <para>Sets the maximum number of suggestions to be retrieved from each individual shard.</para>
	/// </summary>
	public TermSuggesterDescriptor ShardSize(int? shardSize)
	{
		ShardSizeValue = shardSize;
		return Self;
	}

	public TermSuggesterDescriptor Size(int? size)
	{
		SizeValue = size;
		return Self;
	}

	/// <summary>
	/// <para>Defines how suggestions should be sorted per suggest text term.</para>
	/// </summary>
	public TermSuggesterDescriptor Sort(Elastic.Clients.Elasticsearch.Serverless.Core.Search.SuggestSort? sort)
	{
		SortValue = sort;
		return Self;
	}

	/// <summary>
	/// <para>The string distance implementation to use for comparing how similar suggested terms are.</para>
	/// </summary>
	public TermSuggesterDescriptor StringDistance(Elastic.Clients.Elasticsearch.Serverless.Core.Search.StringDistance? stringDistance)
	{
		StringDistanceValue = stringDistance;
		return Self;
	}

	/// <summary>
	/// <para>Controls what suggestions are included or controls for what suggest text terms, suggestions should be suggested.</para>
	/// </summary>
	public TermSuggesterDescriptor SuggestMode(Elastic.Clients.Elasticsearch.Serverless.SuggestMode? suggestMode)
	{
		SuggestModeValue = suggestMode;
		return Self;
	}

	/// <summary>
	/// <para>The suggest text.<br/>Needs to be set globally or per suggestion.</para>
	/// </summary>
	public TermSuggesterDescriptor Text(string? text)
	{
		TextValue = text;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (!string.IsNullOrEmpty(AnalyzerValue))
		{
			writer.WritePropertyName("analyzer");
			writer.WriteStringValue(AnalyzerValue);
		}

		writer.WritePropertyName("field");
		JsonSerializer.Serialize(writer, FieldValue, options);
		if (LowercaseTermsValue.HasValue)
		{
			writer.WritePropertyName("lowercase_terms");
			writer.WriteBooleanValue(LowercaseTermsValue.Value);
		}

		if (MaxEditsValue.HasValue)
		{
			writer.WritePropertyName("max_edits");
			writer.WriteNumberValue(MaxEditsValue.Value);
		}

		if (MaxInspectionsValue.HasValue)
		{
			writer.WritePropertyName("max_inspections");
			writer.WriteNumberValue(MaxInspectionsValue.Value);
		}

		if (MaxTermFreqValue.HasValue)
		{
			writer.WritePropertyName("max_term_freq");
			writer.WriteNumberValue(MaxTermFreqValue.Value);
		}

		if (MinDocFreqValue.HasValue)
		{
			writer.WritePropertyName("min_doc_freq");
			writer.WriteNumberValue(MinDocFreqValue.Value);
		}

		if (MinWordLengthValue.HasValue)
		{
			writer.WritePropertyName("min_word_length");
			writer.WriteNumberValue(MinWordLengthValue.Value);
		}

		if (PrefixLengthValue.HasValue)
		{
			writer.WritePropertyName("prefix_length");
			writer.WriteNumberValue(PrefixLengthValue.Value);
		}

		if (ShardSizeValue.HasValue)
		{
			writer.WritePropertyName("shard_size");
			writer.WriteNumberValue(ShardSizeValue.Value);
		}

		if (SizeValue.HasValue)
		{
			writer.WritePropertyName("size");
			writer.WriteNumberValue(SizeValue.Value);
		}

		if (SortValue is not null)
		{
			writer.WritePropertyName("sort");
			JsonSerializer.Serialize(writer, SortValue, options);
		}

		if (StringDistanceValue is not null)
		{
			writer.WritePropertyName("string_distance");
			JsonSerializer.Serialize(writer, StringDistanceValue, options);
		}

		if (SuggestModeValue is not null)
		{
			writer.WritePropertyName("suggest_mode");
			JsonSerializer.Serialize(writer, SuggestModeValue, options);
		}

		if (!string.IsNullOrEmpty(TextValue))
		{
			writer.WritePropertyName("text");
			writer.WriteStringValue(TextValue);
		}

		writer.WriteEndObject();
	}
}